<?php
/*
 * @Description    : 
 * @Version        : 1.0.0
 * @Author         : QianLong
 * @Date           : 2020-02-08 15:01:43
 * @LastEditors    : QianLong
 * @LastEditTime   : 2024-05-10 17:40:49
 */

declare(strict_types=1);

namespace App\Controller;

use App\Constants\Status;
use App\Exception\ApiException;
use App\Service\Common;
use Qianlong\Validate\Validate;

class ShortController extends AbstractController
{
  public function toUrl($id = '')
  {
    // 重新匹配ID，防止其他干扰
    preg_match('/^[_a-zA-Z0-9\-]+/', $id, $match);
    if (isset($match[0]) && !empty($match[0])) {
      $id = $match[0];
    }
    $where['_id'] = $id;
    $infoData = mongodb2()->short_url->findOne($where);
    $infoData = json_decode(json_encode($infoData), true);
    if (empty($infoData)) {
      throw new ApiException(-1, '内容无效');
    }
    $userInfo = $this->redisCache->getUserInfoById($infoData['uid']);
    if ($userInfo['status'] != 1) {
      unset($userInfo);
      throw new ApiException(-1, '用户状态不正常，请联系柠聚开发平台客服进行处理。开发者官网：http://www.21ds.cn');
    }
    if ($infoData['expire_time'] != 99999 && $infoData['expire_time'] < time()) {
      throw new ApiException(-1, '链接失效');
    }
    if (isset($infoData['url_type']) && $infoData['url_type'] == 2) {
      $page = '';
      $query = '';
      if (isset($infoData['page']) && !empty($infoData['page'])) {
        $parseDate = parse_url($infoData['page']);
        $page = $parseDate['path'];
        $query = isset($parseDate['query'])? $parseDate['query']:'';
      }
      $resultLink = (new Common)->getMiniAppUrlLink($infoData['ma_id'], $page,$query);
      if ($resultLink['code'] == 200) {
        $infoData['url'] = $resultLink['data']['url_link'];
      }else{
        throw new ApiException(-1, '链接获取失败:'.$resultLink['msg']);
      }
    }
    $this->insertLog($id, $infoData['uid']);
    return $this->response->redirect($infoData['url']);
  }
  public function insertLog($id, $uid)
  {
    $remoteIp = $this->dataResource->getClientIp($this->request);
    $new_uv = $this->redisCache->isNewUv($remoteIp, $id);
    $where['hour'] = date('YmdH');
    $where['s_id'] = $id;
    $hasLog = mongodb2()->short_url_log->findOne($where);
    if (empty($hasLog)) {
      $insert['_id'] = createId();
      $insert['date'] = date('Ymd');
      $insert['hour'] = date('YmdH');
      $insert['only_hour'] = date('H') . ':00';
      $insert['hour_stamp'] = strtotime(date('Y-m-d H') . ':00:00');
      $insert['month'] = date('Ym');
      $insert['year'] = date('Y');
      $insert['create'] = time();
      $insert['s_id'] = $id;
      $insert['uid'] = (int) $uid;
      $insert['pv'] = 1;
      $insert['uv'] = 0;
      if ($new_uv == true) {
        $insert['uv'] = 1;
      }
      mongodb2()->short_url_log->insertOne($insert);
    } else {
      if ($new_uv == true) {
        mongodb2()->short_url_log->updateOne($where, ['$inc' => ['pv' => 1, 'uv' => 1]]);
      } else {
        mongodb2()->short_url_log->updateOne($where, ['$inc' => ['pv' => 1]]);
      }
    }
  }
  public function code62($x)
  {
    $show = '';
    while ($x > 0) {
      $s = $x % 62;
      if ($s > 35) {
        $s = chr($s + 61);
      } elseif ($s > 9 && $s <= 35) {
        $s = chr($s + 55);
      }
      $show .= $s;
      $x = floor($x / 62);
    }
    return $show;
  }
  public function make_short_id($url)
  {
    $url = crc32($url);
    $result = sprintf("%u", $url);
    return $this->code62($result);
  }
  public function make_short_url()
  {
    $valitor = new Validate();
    $valitor->addColumn('title')->required();
    $valitor->addColumn('url')->required();
    $valitor->addColumn('expire')->required();
    if ($valitor && !$this->validate($valitor)) {
      throw new ApiException(-1, $valitor->getError()->__toString());
    }
    $param = $this->request->all();
    $urlData['_id'] = $this->make_short_id($param['url'].createId());
    $urlData['expire'] = (int) $param['expire'];
    if ($urlData['expire'] != '99999') {
      $urlData['expire_time'] = time() + (int) $urlData['expire'] * 86400;
    }
    $userInfo = $this->dataResource->getUserInfo();
    $urlData['title'] = $param['title'];
    $urlData['url'] = $param['url'];
    $urlData['create_time'] = time();
    $urlData['uid'] = (int)$userInfo['uid'];
    mongodb2()->short_url->insertOne($urlData);
    return $this->response->json(Status::CODE_OK, 'success', ['short_url'=>'https://21ds.cn/u/'.$urlData['_id'],'id'=> $urlData['_id']]);
  }
}
